package jp.eisbahn.mgapi.http;

import java.io.InputStream;
import java.util.Map;

/**
 * This class represents a HTTP request you want to access.
 * @author Yoichiro Tanaka
 */
public class HttpRequest {

    /** URL included query parameters. */
    private String url;
    /** The map object which has each parameter written on the request body. */
    private Map<String, Object> parameterMap;
    /** The content type. */
    private ContentType contentType;
    /** The HTTP method. */
    private HttpMethod method;
    /** The map object which has each header had into the request header. */
    private Map<String, String> headerMap;
    /** The input stream for a request body. */
    private InputStream bodyStream;

    /**
     * Initialize this instance.
     * @param newUrl URL.
     * @param newParameterMap Parameter map.
     * @param newMethod HTTP method.
     * @param newContentType The content type.
     * @param newHeaderMap The request header values.
     */
    public HttpRequest(
            final String newUrl,
            final Map<String, Object> newParameterMap,
            final HttpMethod newMethod,
            final ContentType newContentType,
            final Map<String, String> newHeaderMap) {
        super();
        url = newUrl;
        parameterMap = newParameterMap;
        method = newMethod;
        contentType = newContentType;
        headerMap = newHeaderMap;
    }

    /**
     * Initialize this instance.
     * @param newUrl URL.
     * @param newParameterMap Parameter map.
     * @param newMethod HTTP method.
     * @param newContentType The content type.
     */
    public HttpRequest(
            final String newUrl,
            final Map<String, Object> newParameterMap,
            final HttpMethod newMethod,
            final ContentType newContentType) {
        this(newUrl, newParameterMap, newMethod, newContentType, null);
    }

    /**
     * Initialize this instance.
     * @param newUrl URL.
     * @param newBodyStream Input stream for a request body.
     * @param newMethod HTTP method.
     * @param newContentType The content type.
     * @param newHeaderMap The request header values.
     */
    public HttpRequest(
            final String newUrl,
            final InputStream newBodyStream,
            final HttpMethod newMethod,
            final ContentType newContentType,
            final Map<String, String> newHeaderMap) {
        super();
        url = newUrl;
        bodyStream = newBodyStream;
        method = newMethod;
        contentType = newContentType;
        headerMap = newHeaderMap;
    }

    /**
     * Retrieve the URL.
     * @return The URL string.
     */
    public final String getUrl() {
        return url;
    }

    /**
     * The map object which has each parameter written into the request body.
     * @return The parameter map.
     */
    public final Map<String, Object> getParameterMap() {
        return parameterMap;
    }

    /**
     * Retrieve whether this request is for output or not.
     * @return If for output, return true.
     */
    public final boolean isDoOuput() {
        switch(method) {
            case GET:
            case DELETE:
                return false;
            case POST:
            case PUT:
                return parameterMap != null || bodyStream != null;
            default:
                throw new IllegalStateException("HttpMethod not set.");
        }
    }

    /**
     * Retrieve the content type.
     * @return The content type value.
     */
    public final ContentType getContentType() {
        return contentType;
    }

    /**
     * Retrieve the HTTP method.
     * @return The HTTP method value.
     */
    public final HttpMethod getMethod() {
        return method;
    }

    /**
     * Retrieve the map object which has request header values.
     * @return The map object.
     */
    public final Map<String, String> getHeaderMap() {
        return headerMap;
    }

    /**
     * Retrieve an input stream for a request body.
     * @return The input stream.
     */
    public final InputStream getBodyStream() {
        return bodyStream;
    }

}
